package com.sjf.JavaNIO.channel;

import org.junit.Test;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author <huangtang>
 * @since 2022/4/13 17:55
 **/
public class DatagramChannelDemo {

    //发送的实现
    @Test
    public void sendDatagram () throws Exception {
        //打开DatagramChanel
        DatagramChannel sendChannel = DatagramChannel.open ();
        InetSocketAddress sendAddress = new InetSocketAddress ("127.0.0.1" , 9999);

        //发送
        while (true) {
            ByteBuffer buffer = ByteBuffer.wrap ("发送数据包".getBytes (StandardCharsets.UTF_8));
            sendChannel.send (buffer , sendAddress);
            System.out.println ("已经完成发送");
            Thread.sleep (3000);
        }
    }

    //接收的实现
    @Test
    public void receiveDatagram () throws Exception {
        //打开DatagramChannel
        DatagramChannel receiveChannel = DatagramChannel.open ();
        InetSocketAddress receiveAddress = new InetSocketAddress (9999);

        //绑定端口
        receiveChannel.bind (receiveAddress);

        //buffer
        ByteBuffer receiveBuffer = ByteBuffer.allocate (1024);
        receiveBuffer.clear ();
        //接收
        while (true) {
            //将receive中接收到数据写入到buffer缓冲区中
            SocketAddress socketAddress = receiveChannel.receive (receiveBuffer);
            //position指针指向开头，用于下方打印缓冲区内容
            receiveBuffer.flip ();
            //打印发送方地址
            System.out.println ("发送方地址：" + socketAddress.toString ());
            //打印发送的内容
            System.out.println ("发送的内容：" + StandardCharsets.UTF_8.decode (receiveBuffer));
        }
    }

    /**
     * DatagramChannel创建连接(填写对应的IP地址和端口号)将缓冲区的数据通过write方法写入channel中，再通过read方法将channel中的数据读入另一个缓冲区中
     * 以此来达到UDP通信方式
     *
     * @throws Exception
     */
    @Test
    public void testConnect () throws Exception {
        //打开DatagramChannel
        DatagramChannel connectChannel = DatagramChannel.open ();
        //绑定
        connectChannel.bind (new InetSocketAddress (9999));

        //创建连接
        connectChannel.connect (new InetSocketAddress ("127.0.0.1" , 9999));

        //write方法
        //从给定的buffer缓冲区中读取数据并写入到connectChannel中
        connectChannel.write (ByteBuffer.wrap ("write方法发送数据包".getBytes (StandardCharsets.UTF_8)));

        //read方法
        //创建缓冲区将从channel中读取数据到该缓冲区中
        ByteBuffer readBuffer = ByteBuffer.allocate (1024);
        while (true) {
            //使用前先clear
            readBuffer.clear ();
            //将channel中的数据读取到buffer中
            connectChannel.read (readBuffer);
            //反转缓存区下标用于下方decode打印缓冲区数据
            readBuffer.flip ();
            //打印缓冲区内容
            System.out.println (StandardCharsets.UTF_8.decode (readBuffer));
        }
    }

    public static void main ( String[] args ) {
        //
    }
}
